package com.tbit.main.util.weixin;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tbit.main.constant.WeixinConfig;
import lombok.extern.slf4j.Slf4j;

import javax.net.ssl.*;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * SSL访问
 *
 * @author Leon
 * 2014-7-15 下午03:45:59
 */
@Slf4j
public class MyX509TrustManager implements X509TrustManager {
    /*微信accessToken*/
    private static String weixinAccessToken = null;
    /*获取时间*/
    private static long getTime = System.currentTimeMillis();
    /*有效时间*/
    private static long effectiveTime = 1 * 3600 * 1000;

    X509TrustManager sunJSSEX509TrustManager;

    MyX509TrustManager() throws Exception {
        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(MyX509TrustManager.class.getResourceAsStream("/weixin.keystore"), "123456".toCharArray());
        TrustManagerFactory tmf =
                TrustManagerFactory.getInstance("SunX509", "SunJSSE");
        tmf.init(ks);
        TrustManager tms[] = tmf.getTrustManagers();
        for (int i = 0; i < tms.length; i++) {
            if (tms[i] instanceof X509TrustManager) {
                sunJSSEX509TrustManager = (X509TrustManager) tms[i];
                return;
            }
        }
        throw new Exception("Couldn't initialize");
    }

    /**
     * 获取openId
     */
    public static String getOpenId(String code) {
        String openid = null;
        try {
            TrustManager[] tm = {new MyX509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            URL myURL = new URL("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + WeixinConfig.appid + "&secret=" + WeixinConfig.appsecret + "&code=" + code + "&grant_type=authorization_code");
            HttpsURLConnection httpsConn = (HttpsURLConnection) myURL.openConnection();
            httpsConn.setSSLSocketFactory(ssf);
            InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream(), "UTF-8");
            StringBuffer result = new StringBuffer();
            int respInt = insr.read();
            while (respInt != -1) {
                result.append((char) respInt);
                respInt = insr.read();
            }
            JSONObject object = JSON.parseObject(result.toString());
            if (object.getString("errcode") == null) {
                openid = object.getString("openid");
            } else {
                log.error("获取openId失败,code=" + code + ",微信回复=" + result.toString());
            }
        } catch (Exception e) {
            log.error("获取openId异常", e);
        }

        return openid;
    }

    /**
     * 获取accessToken
     */
    public synchronized static String getAccessToken() {
        /*判断时效性(1个小时获取一次)*/
        if (weixinAccessToken != null && (System.currentTimeMillis() - getTime) <= effectiveTime) {
            return weixinAccessToken;
        }

        try {
            TrustManager[] tm = {new MyX509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            URL myURL = new URL("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + WeixinConfig.appid + "&secret=" + WeixinConfig.appsecret + "&code");
            HttpsURLConnection httpsConn = (HttpsURLConnection) myURL.openConnection();
            httpsConn.setSSLSocketFactory(ssf);
            InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream(), "UTF-8");
            StringBuffer result = new StringBuffer();
            int respInt = insr.read();
            while (respInt != -1) {
                result.append((char) respInt);
                respInt = insr.read();
            }
            log.info("获取微信accessToken：" + result.toString());
            JSONObject object = JSON.parseObject(result.toString());
            if (object.getString("errcode") == null) {
                /*更新accessToken*/
                weixinAccessToken = object.getString("access_token");
                /*更新获取时间*/
                getTime = System.currentTimeMillis();
            }
        } catch (Exception e) {
            log.error("获取access_token异常", e);
        }

        return weixinAccessToken;
    }

    /**
     * 主动推送模板消息
     */
    public static void pushMessage(String accessToken, String content) {
        try {
            TrustManager[] tm = {new MyX509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            URL myURL = new URL("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken);
            HttpsURLConnection httpsConn = (HttpsURLConnection) myURL.openConnection();
            httpsConn.setSSLSocketFactory(ssf);
            httpsConn.setRequestMethod("POST");
            httpsConn.setDoOutput(true);
            OutputStream outputStream = httpsConn.getOutputStream();
            outputStream.write(content.getBytes("UTF-8"));
            outputStream.close();

            InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream(), "UTF-8");
            StringBuffer result = new StringBuffer();
            int respInt = insr.read();
            while (respInt != -1) {
                result.append((char) respInt);
                respInt = insr.read();
            }

            JSONObject object = JSON.parseObject(result.toString());
            if (object.getInteger("errcode") != 0) {
                /*返回错误代码40001重置*/
                if (object.getInteger("errcode") == 40001) {
                    log.error("重置微信AccessToken");
                    weixinAccessToken = null;
                }
                log.error("语音模版推送:" + result);
            }
        } catch (Exception e) {
            log.error("主动推送模版消息失败", e);
        }
    }

    public static void main(String[] args) {
//    	System.out.println(getAccessToken());

        System.out.println(getOpenId("001iwxIF0mLqJc2rrRGF0K2HIF0iwxIY"));

    }

    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        try {
            sunJSSEX509TrustManager.checkClientTrusted(chain, authType);
        } catch (CertificateException excep) {
        }
    }

    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        try {
            sunJSSEX509TrustManager.checkServerTrusted(chain, authType);
        } catch (CertificateException excep) {
        }
    }

    public X509Certificate[] getAcceptedIssuers() {
        return sunJSSEX509TrustManager.getAcceptedIssuers();
    }
}

        